package com.persia.aop;

import com.persia.exception.InValidValueException;
import com.persia.tool.CollectionTool;
import com.persia.tool.InputValidator;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 进行参数校验的aop
 * @author caibosi
 * @created 2014-02-10
 */
@Aspect
@Component
public class CheckParamAop {

    //dao包及其子包下的任何类的任何方法（任意参数）
    @Pointcut("execution(public * com.persia.dao..*.*(..))")
    public void daoInput() {

    }

    @Pointcut("execution(public * com.persia.service..*.*(..))")
    public void serviceInput() {

    }

    @Pointcut("execution(public * com.persia.controller..*.*(..))")
    public void controllerInput(){

    }

    @Before(value = "daoInput()")
    public void handleDaoInvalidParam(JoinPoint joinPoint){
         throwInvalidParamException(joinPoint);
    }

    @Before(value = "serviceInput()")
    public void handleServiceInvalidParam(JoinPoint joinPoint){
         throwInvalidParamException(joinPoint);
    }

    @Before(value = "controllerInput()")
    public void handleControllerInvalidParam(JoinPoint joinPoint){
         throwInvalidParamException(joinPoint);
    }

    @Around(value = "controllerInput()")
    public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
        try{
            Object returnObj = pjp.proceed(pjp.getArgs());
            return returnObj;
        }catch (InValidValueException ex){
            Signature signature = pjp.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            Class<?> returnType = method.getReturnType();
            //返回页面
            if(returnType == ModelAndView.class){
               return new ModelAndView("invalidInput.ftl");
            }else if (returnType == Map.class || returnType == Object.class){
               //ajax 返回json
                Map<String, Object> relMap = new HashMap<String, Object>();
                relMap.put("isSuccess",0);
                return relMap;
            }else if (returnType == String.class){
                return "error";
            }
        }
        return null;
    }

    /**
     * 处理输入参数的校验
     * @param joinPoint
     */
    private void throwInvalidParamException(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        if(CollectionTool.isEmpty(args))
            throw new InValidValueException("参数不能为空");
        for(Object arg : args){
            if(arg instanceof String){
                InputValidator.checkNotEmpty((String)arg,"should not be empty");
            }else{
                InputValidator.checkNotNull(arg,"should not be null");
            }
        }
    }


}
